package edu.scau.divineplace.config.global.exception;

import edu.scau.divineplace.entity.response.Result;
import edu.scau.divineplace.util.ResultUtil;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author: x1aolone
 * @Date: 2020/12/9 13:33
 */
@RestControllerAdvice(basePackages = {"edu.scau.divineplace"})
public class ExceptionControllerAdvice {

    /**
     * 处理 hibernate-validatorhibernate-validator框架进行入参校验时产生的异常
     * 处理javax.validation入参校验时产生的异常，因为普通的valid不能处理平铺参数
     * @param e
     * @return
     */
    @ExceptionHandler(value = {MethodArgumentNotValidException.class, ConstraintViolationException.class, BindException.class})
    public Result MethodArgumentNotValidExceptionHandler(Exception e) {
        StringBuilder message = new StringBuilder();
        if (e instanceof MethodArgumentNotValidException) {
            e.printStackTrace();
            // 从异常对象中拿到ObjectError对象
            ObjectError objectError = ((MethodArgumentNotValidException) e).getBindingResult().getAllErrors().get(0);
            // 然后提取错误提示信息
            message.append(objectError.getDefaultMessage());
        } else if (e instanceof ConstraintViolationException) {
            message.append(
                    ((ConstraintViolationException) e).getConstraintViolations()
                    .stream()
                    .map(x -> "[Path: " + x.getPropertyPath() + ", Message: " + x.getMessage() + "]")
                    .collect(Collectors.joining(", ")));
        } else if (e instanceof BindException) {
            message.append(((BindException) e).getBindingResult()
                    .getAllErrors()
                    .stream()
                    .map(ObjectError::getDefaultMessage)
                    .collect(Collectors.joining(","))
            );
        }
        return ResultUtil.error(message.toString());
    }

    @ExceptionHandler(Exception.class)
    public Result ExceptionHandler(Exception e) {
        e.printStackTrace();
        return ResultUtil.error("error: " + e.getMessage());
    }

}
